package com.javaee.controller;

import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.javaee.util.ResultOutDto;
import com.javaee.weixin.Configure;
import com.javaee.weixin.entity.Ticket;
import com.javaee.weixin.util.CommonDataUtils;
import com.javaee.weixin.util.OAuth2AccessToken;
import com.javaee.weixin.util.SignUtils;
import com.javaee.weixin.util.WeixinUtils;

import net.sf.json.JSONObject;

/**
 * 微信公众号授权,支付,分享
 * @author lyl
 */
@Controller
@RequestMapping("/front/weixin/")
public class WeiXinController {

	public static Logger logger = LoggerFactory.getLogger(WeiXinController.class);

	/**
	 * 微信公众号(H5)支付
	 * 
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("wxPay")
	public Map<String, Object> wxPay(HttpServletRequest request) throws Exception {
		// 请求参数集合，要按字典序排列
		TreeMap<String, Object> requestParamMap = new TreeMap<String, Object>();
		String ativict_id = request.getParameter("ativict_id");

		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		DecimalFormat numberFormat = new DecimalFormat("#");
		requestParamMap.put("appid", Configure.APP_ID);
		requestParamMap.put("mch_id", Configure.MCH_ID);
		requestParamMap.put("nonce_str", WeixinUtils.getRandomStringByLength(32));
		requestParamMap.put("body", "公益平台");
		requestParamMap.put("out_trade_no", uuid);// 订单号
		requestParamMap.put("total_fee", 1);// 金钱单位:分
		requestParamMap.put("spbill_create_ip", Configure.CLIENT_IP);
		requestParamMap.put("notify_url", Configure.DOMAIN_NAME + "/front/weixin/notifyUrl.shtml");
		requestParamMap.put("trade_type", "JSAPI");
		requestParamMap.put("openid", request.getParameter("openid"));
		requestParamMap.put("attach", ativict_id);
		String device_info = request.getParameter("product_id");
		requestParamMap.put("device_info", device_info);// 此处为凭证ID,根据自己的业务更改，可以不填写此参数
		System.out.println("=======凭证ID========" + request.getParameter("product_id"));
		String sign = SignUtils.getMD5Sign(requestParamMap);
		requestParamMap.put("sign", sign);
		// 请求API获得回包数据
		String requestXML = WeixinUtils.getRequestXml(requestParamMap);
		String responseXML = CommonDataUtils.httpsRequest(Configure.I_pay, "POST", requestXML);
		Map<String, Object> responseParamMap = WeixinUtils.getMapFromXML(responseXML);
		// 如果支付失败
		if (responseParamMap.get("return_code").equals("FAIL")) {
			responseParamMap.put("orderNo", request.getParameter("ativict_id"));// 活动号
			return responseParamMap;
		}
		TreeMap<String, Object> responseParamMap2 = new TreeMap<String, Object>();
		// 对比返回的签名，如果签名一致则装填返回参数
		String sign2 = responseParamMap.remove("sign") + "";
		String sign3 = SignUtils.getMD5Sign(responseParamMap);
		if (sign2.equals(sign3)) {
			responseParamMap2.put("timeStamp", WeixinUtils.createTimestamp());
			responseParamMap2.put("package", "prepay_id=" + responseParamMap.get("prepay_id") + "");
			responseParamMap2.put("appId", Configure.APP_ID);
			responseParamMap2.put("signType", "MD5");
			responseParamMap2.put("nonceStr", responseParamMap.get("nonce_str"));
			responseParamMap2.put("paySign", SignUtils.getMD5Sign(responseParamMap2));
			responseParamMap2.put("orderNo", request.getParameter("ativict_id"));// 订单号
		}
		return responseParamMap2;
	}

	/**
	 * 微信支付回调地址，支付结果通知（异步）
	 * 确保回调地址能外网正常访问，否则微信回调失败
	 */
	@RequestMapping("notifyUrl")
	public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 把输入流携带的字节数组数据转换成字符串
		String notifyXML = IOUtils.toString(request.getInputStream());
		String responseXML = "";
		if (notifyXML != null && !notifyXML.trim().isEmpty()) {
			Map<String, Object> notifyMap = WeixinUtils.getMapFromXML(notifyXML);
			// 添加申请记录
			String attach = notifyMap.get("attach") + ""; // 此处是活动号
			String openid = notifyMap.get("openid").toString();// openid
			String device_info = notifyMap.get("device_info").toString();// 此处为凭证ID
			// 支付成功
			/*
			 * String attach = request.getParameter("attach"); String openid =
			 * request.getParameter("openid"); String device_info =
			 * request.getParameter("device_info");
			 */

			if ("SUCCESS".equals(notifyMap.get("result_code") + "")) {
				responseXML = "<xml><return_code><![CDATA[SUCCESS]]></return_code>"
						+ "<return_msg><![CDATA[OK]]></return_msg></xml>";
				// 支付成功,进行逻辑处理

				//写自己的逻辑....
				}
			} else {// 支付失败
				responseXML = responseXML.replaceAll("SUCCESS", "FAIL");
		}
		IOUtils.write(responseXML.getBytes(), response.getOutputStream());
	}

	/**
	 * 获取微信用户的code，以此换取网页授权access_token 获取code,用来获取用户的openid
	 */
	@RequestMapping("getCode")
	public void getCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter("code");
		String state = request.getParameter("state");
		OAuth2AccessToken oAuth2AccessToken = CommonDataUtils.getOAuth2AccessToken(code);
		Map<String, Object> requestParamMap = new HashMap<String, Object>();
		requestParamMap.put("ACCESS_TOKEN", oAuth2AccessToken.getAccessToken());
		requestParamMap.put("OPENID", oAuth2AccessToken.getOpenId());
		String responseJson = CommonDataUtils.formUpload(Configure.I_userinfo, requestParamMap);

		// JSONObject jsonObject2=JSONObject.fromObject(responseJson);
		if(state.equals("")||state.equals(null)||state.equals("STATE")){
			// 重定向到首页并且带上用户信息
			response.sendRedirect(
					"http://wecake.cc/wap_gy/home.html?wechatFormMap= " + URLEncoder.encode(responseJson, "UTF-8"));// 用户信息回传
		}else{
			response.sendRedirect(
					state+"?wechatFormMap=" + URLEncoder.encode(responseJson, "UTF-8"));// 用户信息回传
		}
		
	}


	/**
	 * 检验授权凭证access_token是否有效
	 * 
	 * @param jsonObject
	 *            该对象是访问获取网页授权access_token接口返回的参数
	 * @return JSONObject对象
	 */
	private JSONObject checkValidity(JSONObject jsonObject) {
		Map<String, Object> requestParamMap = new HashMap<String, Object>();
		requestParamMap.put("ACCESS_TOKEN", jsonObject.getString("access_token"));
		requestParamMap.put("OPENID", jsonObject.getString("openid"));
		String responseJson = CommonDataUtils.formUpload(Configure.I_auth, requestParamMap);
		JSONObject jsonObject2 = JSONObject.fromObject(responseJson);
		return jsonObject2;
	}

	/**
	 * 通过config接口注入权限验证配置 获取jsapi_ticket
	 * 微信分享需要获取签名，可调用此接口
	 * @param url
	 *            调用该方法的页面地址
	 */
	@ResponseBody
	@RequestMapping("/wxConfig")
	public Map<String, Object> wxConfig(HttpServletRequest request, String url) throws Exception {
		String appId = request.getParameter("appId");
		String appSecret = "";
		if ("wx8990bcdbc70c24fa".equals(appId)) {
			appSecret = "f18760cfd838ae70184cfc03ba832d47";
		} else if ("wx62d14b264c90bb71".equals(appId)) {
			appSecret = "ec75188473a56e076b8257c895c6f67c";
		}

		TreeMap<String, Object> responseParamMap = new TreeMap<String, Object>();
		// 1、获取jsapi_ticket
		Ticket ticket = CommonDataUtils.getTicket(appId, appSecret);

		String timestamp = WeixinUtils.createTimestamp();
		String nonceStr = WeixinUtils.createNonceStr();
		// 2、生成SHA1签名
		String sha1Sign = SignUtils.getSHA1Sign(ticket.getTicket(), url, nonceStr, timestamp);
		// 3、装填返回参数
		responseParamMap.put("appId", StringUtils.isEmpty(appId) ? Configure.APP_ID : appId);
		responseParamMap.put("timestamp", timestamp);
		responseParamMap.put("nonceStr", nonceStr);
		responseParamMap.put("signature", sha1Sign);

		System.out.println((StringUtils.isEmpty(appId) ? Configure.APP_ID : appId) + "|" + ticket.getTicket() + "|"
				+ timestamp + "|" + nonceStr + "|" + sha1Sign);
		return responseParamMap;
	}
	
	
	//*********** ***********
	/**
	 * 微信授权,获取凭证
	 * @param request
	 * @param url
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/getjsapiTicket")
	public ResultOutDto getjsapiTicket(HttpServletRequest request, String url) throws Exception {
		HashMap<Object, Object> map = new HashMap<Object,Object>();
		try {
			String appId = request.getParameter("appId");
			String appSecret = "";
			if ("wx8990bcdbc70c24fa".equals(appId)) {
				appSecret = "f18760cfd838ae70184cfc03ba832d47";
			} else if ("wx62d14b264c90bb71".equals(appId)) {
				appSecret = "ec75188473a56e076b8257c895c6f67c";
			}

			TreeMap<String, Object> responseParamMap = new TreeMap<String, Object>();
			// 1、获取jsapi_ticket
			Ticket ticket = CommonDataUtils.getTicket(appId, appSecret);

			String timestamp = WeixinUtils.createTimestamp();
			String nonceStr = WeixinUtils.createNonceStr();
			// 2、生成SHA1签名
			String sha1Sign = SignUtils.getSHA1Sign(ticket.getTicket(), url, nonceStr, timestamp);
			// 3、装填返回参数
			responseParamMap.put("appId", StringUtils.isEmpty(appId) ? Configure.APP_ID : appId);
			responseParamMap.put("timestamp", timestamp);
			responseParamMap.put("nonceStr", nonceStr);
			responseParamMap.put("signature", sha1Sign);

			System.out.println((StringUtils.isEmpty(appId) ? Configure.APP_ID : appId) + "|" + ticket.getTicket() + "|"
					+ timestamp + "|" + nonceStr + "|" + sha1Sign+"|"+url);
			map.put("data", responseParamMap);
			return ResultOutDto.ok(map);
		} catch (Exception e) {
			map.put("err", "系统错误!");
			return ResultOutDto.ok(map);
		}
		
	}
}
